package com.daisuxia.lianlian.util;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;



/**
* 常用工具函数
* @author guoyx e-mail:guoyx@lianlian.com
* @version :1.0
*
*/
public class LLPayUtil{
    /**
     * str空判断
     * @param str
     * @return
     * @author guoyx
     */
    public static boolean isnull(String str)
    {
        if (StringUtils.isBlank(str) || str.equalsIgnoreCase("null"))
        {
            return true;
        } else
            return false;
    }

    /**
     * 获取当前时间str，格式yyyyMMddHHmmss
     * @return
     * @author guoyx
     */
    public static String getCurrentDateTimeStr()
    {
        SimpleDateFormat dataFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        Date date = new Date();
        String timeString = dataFormat.format(date);
        return timeString;
    }

    /**
     * 
     * 功能描述：获取真实的IP地址
     * @param request
     * @return
     * @author guoyx
     */
    public static String getIpAddr(HttpServletRequest request)
    {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
        {
            ip = request.getRemoteAddr();
        }
        if (!isnull(ip) && ip.contains(","))
        {
            String[] ips = ip.split(",");
            ip = ips[ips.length - 1];
        }
        //转换IP 格式
        if(!isnull(ip)){
            ip=ip.replace(".", "_");
        }
        return ip;
    }


    /**
     * 根据JavaObject生成待签名串
     * @param object
     * @return
     * @author duj
     */
    public static String genSignDataByJavaObject(Object object)
    {
    	String jsonString = JSONObject.toJSONString(object);
		JSONObject jsonObject = JSONObject.parseObject(jsonString);
    	
        StringBuffer content = new StringBuffer(1024);

        // 按照key做首字母升序排列
        List<String> keys = new ArrayList<String>(jsonObject.keySet());
        Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
        for (int i = 0; i < keys.size(); i++)
        {
            String key = (String) keys.get(i);
            if ("sign".equals(key))
            {
                continue;
            }
            String value = jsonObject.getString(key);
            // 空串不参与签名
            if (isnull(value))
            {
                continue;
            }
            content.append((i == 0 ? "" : "&") + key + "=" + value);

        }
        String signSrc = content.toString();
        if (signSrc.startsWith("&"))
        {
            signSrc = signSrc.replaceFirst("&", "");
        }
        return signSrc;
    }
    
    /**
     * 根据JSONObject生成待签名串
     * @param jsonObject
     * @return
     * @author guoyx
     */
    public static String genSignData(JSONObject jsonObject)
    {
        StringBuffer content = new StringBuffer(1024);

        // 按照key做首字母升序排列
        List<String> keys = new ArrayList<String>(jsonObject.keySet());
        Collections.sort(keys, String.CASE_INSENSITIVE_ORDER);
        for (int i = 0; i < keys.size(); i++)
        {
            String key = (String) keys.get(i);
            if ("sign".equals(key))
            {
                continue;
            }
            String value = jsonObject.getString(key);
            // 空串不参与签名
            if (isnull(value))
            {
                continue;
            }
            content.append((i == 0 ? "" : "&") + key + "=" + value);

        }
        String signSrc = content.toString();
        if (signSrc.startsWith("&"))
        {
            signSrc = signSrc.replaceFirst("&", "");
        }
        return signSrc;
    }

    /**
     * 加签
     * 
     * @param reqObj
     * @param rsa_private
     * @param md5_key
     * @return
     * @author guoyx
     */
    public static String addSign(JSONObject reqObj, String rsa_private,
            String md5_key)
    {
        if (reqObj == null)
        {
            return "";
        }
        String sign_type = reqObj.getString("sign_type");
        if (SignTypeEnum.MD5.getCode().equals(sign_type))
        {
            return addSignMD5(reqObj, md5_key);
        } else
        {
            return addSignRSA(reqObj, rsa_private);
        }
    }

    /**
     * MD5签名验证
     * 
     * @param md5_key
     * @param reqObj
     * @return
     * @author guoyx
     */
    private static boolean checkSignMD5(JSONObject reqObj, String md5_key)
    {
//        System.out.println("进入商户[" + reqObj.getString("oid_partner")
//                + "]MD5签名验证");
        if (reqObj == null)
        {
            return false;
        }
        String sign = reqObj.getString("sign");
        // 生成待签名串
        String sign_src = genSignData(reqObj);
//        System.out.println("商户[" + reqObj.getString("oid_partner") + "]待签名原串"
//                + sign_src);
//        System.out.println("商户[" + reqObj.getString("oid_partner") + "]签名串"
//                + sign);
        sign_src += "&key=" + md5_key;
        try
        {
            if (sign.equals(Md5Algorithm.getInstance().md5Digest(
                    sign_src.getBytes("utf-8"))))
            {
//                System.out.println("商户[" + reqObj.getString("oid_partner")
//                        + "]MD5签名验证通过");
                return true;
            } else
            {
//                System.out.println("商户[" + reqObj.getString("oid_partner")
//                        + "]MD5签名验证未通过");
                return false;
            }
        } catch (UnsupportedEncodingException e)
        {
            System.out.println("商户[" + reqObj.getString("oid_partner")
                    + "]MD5签名验证异常" + e.getMessage());
            return false;
        }
    }

    /**
     * RSA加签名
     * 
     * @param reqObj
     * @param rsa_private
     * @return
     * @author guoyx
     */
   private static String addSignRSA(JSONObject reqObj, String rsa_private)
    {
//        System.out.println("进入商户[" + reqObj.getString("oid_partner")
//                + "]RSA加签名");
        if (reqObj == null)
        {
            return "";
        }
        // 生成待签名串
        String sign_src = genSignData(reqObj);
//        System.out.println("商户[" + reqObj.getString("oid_partner") + "]加签原串"
//                + sign_src);
        try
        {
            return RSAUtil.sign(rsa_private, sign_src);
        } catch (Exception e)
        {
            System.out.println("商户[" + reqObj.getString("oid_partner")
                    + "]RSA加签名异常" + e.getMessage());
            return "";
        }
    }

    /**
     * MD5加签名
     * 
     * @param reqObj
     * @param md5_key
     * @return
     * @author guoyx
     */
   private static String addSignMD5(JSONObject reqObj, String md5_key)
    {
//        System.out.println("进入商户[" + reqObj.getString("oid_partner")
//                + "]MD5加签名");
        if (reqObj == null)
        {
            return "";
        }
        // 生成待签名串
        
        String sign_src = genSignData(reqObj);
       
        sign_src += "&key=" + md5_key;
//        System.out.println("商户[" + reqObj.getString("oid_partner") + "]加签原串"
//                + sign_src);
        try
        {
            return Md5Algorithm.getInstance().md5Digest(
                    sign_src.getBytes("utf-8"));
        } catch (Exception e)
        {
            System.out.println("商户[" + reqObj.getString("oid_partner")
                    + "]MD5加签名异常" + e.getMessage());
            return "";
        }
    }

   /**
    * post提交流形式的json数据
    * @param urlStr 访问地址
    * @param object 提交json格式数据的原始JavaBean
    * @return 响应结果（json串）
    */
	public static String postJsonByJavaObject(String urlStr, Object object) { 
		StringBuffer sb = new StringBuffer(1024);
       try { 
           //创建连接 
           URL url = new URL(urlStr); 
           HttpURLConnection connection = (HttpURLConnection) url 
                   .openConnection(); 
           connection.setDoOutput(true); 
           connection.setDoInput(true); 
           connection.setRequestMethod("POST"); 
           connection.setUseCaches(false); 
           connection.setInstanceFollowRedirects(true); 
           connection.setRequestProperty("Content-Type", 
                   "application/x-www-form-urlencoded"); 

           connection.connect(); 

           //POST请求 
           DataOutputStream out = new DataOutputStream( 
                   connection.getOutputStream()); 
           String jsonString = JSONObject.toJSONString(object);
           out.writeBytes(jsonString); 
           out.flush(); 
           out.close(); 

           //读取响应 
           BufferedReader reader = new BufferedReader(new InputStreamReader( 
                   connection.getInputStream())); 
           String lines; 
           while ((lines = reader.readLine()) != null) { 
               lines = new String(lines.getBytes(), "utf-8"); 
               sb.append(lines); 
           } 
            
//           System.out.println(sb); 
           reader.close(); 
           // 断开连接 
           connection.disconnect(); 
       } catch (MalformedURLException e) { 
           e.printStackTrace(); 
       } catch (UnsupportedEncodingException e) { 
           e.printStackTrace(); 
       } catch (IOException e) { 
           e.printStackTrace(); 
       }
		return sb.toString(); 

   } 
   
    /**
     * 读取request流
     * @param request
     * @return
     * @author guoyx
     */
    public static String readReqStr(HttpServletRequest request)
    {
        BufferedReader reader = null;
        StringBuilder sb = new StringBuilder(1024);
        try
        {
            reader = new BufferedReader(new InputStreamReader(request
                    .getInputStream(), "utf-8"));
            String line = null;

            while ((line = reader.readLine()) != null)
            {
                sb.append(line);
            }
        } catch (IOException e)
        {
            e.printStackTrace();
        } finally
        {
            try
            {
                if (null != reader)
                {
                    reader.close();
                }
            } catch (IOException e)
            {

            }
        }
        return sb.toString();
    }
}
